/**
 * Project Name:SpringOA
 * File Name:UserAction.java
 * Package Name:com.zml.oa.action
 * Date:2014-11-9上午12:35:50
 *
 */
package cn.tanghom.app.workflow.controller;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import me.kafeitu.demo.activiti.util.Page;

import org.flowable.engine.IdentityService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.repository.ProcessDefinitionQuery;
import org.flowable.idm.api.Group;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import cn.tanghom.app.system.model.Message;
import cn.tanghom.app.system.model.Role;
import cn.tanghom.app.system.model.User;
import cn.tanghom.app.system.service.RoleService;
import cn.tanghom.app.system.service.UserService;
import cn.tanghom.app.workflow.service.IFlowableBaseService;
import cn.tanghom.conf.CommonKey;
import cn.tanghom.support.page.Pager;
import cn.tanghom.support.page.Pagination;
import cn.tanghom.support.page.PaginationThreadUtils;
import cn.tanghom.support.web.BaseController;


import static cn.tanghom.support.web.BaseController.THEME_PATH;

/**
 * @ClassName: UserAction
 * @Description:acitivity用户Controller，显示用户列表，选择用户，选择group下的用户，选择group
 * @author: zml
 * @date: 2014-11-9 上午12:35:50
 *
 */

@Controller
@RequestMapping("/userAction")
public class UserAction {
	private static final Logger logger = Logger.getLogger(UserAction.class);
	
	@Autowired
	private UserService userService;	
	
	@Autowired
	private RoleService roleService;
	
	@Autowired
    private SessionDAO sessionDAO;
	
	@Autowired
    protected IFlowableBaseService activitiBaseService;
	
	@Autowired
	protected IdentityService identityService;
	
	@Resource
    protected RepositoryService repositoryService;
	
	
	@RequiresPermissions("admin:session:forceLogout")
    @RequestMapping("/forceLogout/{sessionId}")
	@ResponseBody
    public Message forceLogout(@PathVariable("sessionId") String sessionId) {
		Message message = new Message();
        try {
            Session session = sessionDAO.readSession(sessionId);
            if(session != null) {
                session.setAttribute(CommonKey.SESSION_FORCE_LOGOUT_KEY, Boolean.TRUE);
            }
            message.setStatus(Boolean.TRUE);
            message.setMessage("强制退出成功！");
        } catch (Exception e) {
        	message.setStatus(Boolean.FALSE);
            message.setMessage("强制退出失败！");
        }
        return message;
    }
	
	/**
	 * 同步所有用户到activiti表
	 * @param redirectAttributes
	 * @return
	 * @throws Exception
	 */
	@RequiresPermissions("admin:user:syncUser")
	@RequestMapping("/syncUserToFlowable")
	@ResponseBody
	public Message syncUserToFlowable() throws Exception {
		Message message = new Message();
		try {
			this.synAllUserAndRoleToFlowable();
			message.setStatus(Boolean.TRUE);
            message.setMessage("同步用户信息成功！");
		} catch (Exception e) {
			message.setStatus(Boolean.FALSE);
            message.setMessage("同步用户信息失败！");
		}
		return message;
	}
	
	//如果执行删除，工作流审批中的代办任务和待签收任务将无法使用。（在act_ru_identitylink将查不到act_id_user、act_id_group和act_id_membership的信息）
	@RequiresPermissions("admin:user:delAllIdentifyData")
	@RequestMapping("/delAllIdentifyData")
	public String delAllIdentifyData(RedirectAttributes redirectAttributes) throws Exception {
		this.deleteAllFlowableIdentifyData();
		redirectAttributes.addFlashAttribute("msg", "成功删除工作流引擎Flowable的用户、角色以及关系！");
		return "redirect:/userAction/toShowUser";
	}  
	
	
	/**
	 * 跳转选择候选人页面-easyui,先显示grouplist
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping(value = "/toChooseUser")
	public ModelAndView toChooseUser(@RequestParam("multiSelect") boolean multiSelect, @RequestParam("taskDefKey") String taskDefKey) throws Exception{
		ModelAndView mv = new ModelAndView(THEME_PATH+"/bpmn/choose_user");
		List<Group> groupList = identityService.createGroupQuery().list();
		mv.addObject("taskDefKey", taskDefKey);
		mv.addObject("multiSelect", multiSelect);
		mv.addObject("groupList", groupList);
		return mv;
	}
	
	/**
	 * 跳转选择group页面-easyui
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping(value = "/toChooseGroup")
	public ModelAndView toChooseGroup() throws Exception{
		ModelAndView mv = new ModelAndView(THEME_PATH+"/bpmn/choose_group");
		List<Group> groupList = identityService.createGroupQuery().list();
		mv.addObject("groupList", groupList);
		return mv;
	}
	
	/**
	 * 在tabs中根据groupId显示用户列表
	 * @return
	 */
	@RequestMapping(value = "/toShowUser")
	public ModelAndView toShowUser(
			@RequestParam(value = "groupId", required = false) String groupId,			
			@RequestParam(value = "multiSelect", required = false) boolean multiSelect, 
			@RequestParam(value = "taskDefKey", required = false) String taskDefKey){
		ModelAndView mv = new ModelAndView(THEME_PATH+"/bpmn/list_user");
		//Pager<User> p = new Pager<User>(page, rows);
		List<User> userList = new ArrayList<>();
		if(groupId == null){
			userList = this.userService.findUserByRole(null);
		}else{
			userList = this.userService.findUserByRole(groupId);
		}
		mv.addObject("userList", userList);
		mv.addObject("groupId", groupId);
		mv.addObject("multiSelect", multiSelect);
		mv.addObject("taskDefKey", taskDefKey);
		return mv;
	}		
	
	
	/**
	 * 获取候选人列表 - easyui
	 * @param page
	 * @param rows
	 * @param groupId
	 * @param flag
	 * @param key
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/chooseUser")
	@ResponseBody
	public ModelAndView chooseUser(	
			@RequestParam(value = "groupId", required = false) String groupId) throws Exception{
		
		Pagination pagination = PaginationThreadUtils.get();
		Pager<User> p = new Pager<User>(pagination.getCurrentPage(), pagination.getPageSize());
		
		List<User> userList = new ArrayList<>();
		if(groupId == null){
			userList = this.userService.findUserByRole(null);
		}else{
			userList = this.userService.findUserByRole(groupId);
		}
		List<Object> jsonList=new ArrayList<Object>(); 
		
		for(User user: userList){
			Map<String, Object> map=new HashMap<String, Object>();
			map.put("id", user.getId());
			map.put("name", user.getUserName());
			map.put("group", user.getOrganizationName());
			map.put("registerDate", user.getCreateTime());
			jsonList.add(map);
		}		
		
		List<Group> groupList = identityService.createGroupQuery().list();
		ModelAndView model = new ModelAndView(THEME_PATH+"/bpmn/choose_user");
		model.addObject("userList", userList);
		model.addObject("groupList", groupList);
		model.addObject("groupId", groupId);
		model.addObject("userMapList", jsonList);
		return model;
	}
	
	/**
	 * easyui
	 * @return
	 */
	@RequestMapping(value = "/toListBpmn")
	public ModelAndView toListBpmn(){
		Pagination pagination = PaginationThreadUtils.get();
		Pager<Object> pager = listBpmn(pagination.getCurrentPage(),pagination.getPageSize());
		
		ModelAndView model = new ModelAndView(THEME_PATH+"/bpmn/list_bpmn");
		model.addObject("bpmnList", pager.getContent());
		model.addObject("total", pager.getTotal());
		return model;
	}
	
	/**
	 * BPMN列表 easyui
	 * @param page
	 * @param rows
	 * @return
	 */
	@RequestMapping(value = "/listBpmn")
	@ResponseBody
	public Pager<Object> listBpmn(
			@RequestParam(value = "page", required = false) Integer page,
    		@RequestParam(value = "rows", required = false) Integer rows){
		Pager<Object> p = new Pager<Object>(page, rows);
		List<Object> jsonList=new ArrayList<Object>(); 
		
		ProcessDefinitionQuery proDefQuery = repositoryService.createProcessDefinitionQuery().orderByDeploymentId().desc();
		Integer totalSum = proDefQuery.list().size();
		int[] pageParams = p.getPageParams(totalSum);
		List<ProcessDefinition> processDefinitionList = proDefQuery.listPage(pageParams[0], pageParams[1]);
		for(ProcessDefinition pd : processDefinitionList){
			Map<String, Object> map=new HashMap<String, Object>();
			map.put("id", pd.getId());
			map.put("name", pd.getName());
			map.put("key", pd.getKey());
			map.put("resourceName", pd.getResourceName());
			map.put("diagramResourceName", pd.getDiagramResourceName());
			jsonList.add(map);
		}
		p.setItems(jsonList);
		p.setTotal(totalSum);
		return p;		
	}
	
	 /**
     * 同步用户、角色数据到工作流
     * @throws Exception
     */   
	public void synAllUserAndRoleToFlowable() throws Exception {		
        
        // 复制角色数据
        synRoleToFlowable();
        
        // 复制用户以及关系数据
        synUserWithRoleToFlowable();
		
	}
 
    /**
     * 删除工作流引擎Flowable的用户、角色以及关系
     * @throws Exception
     */   
	
	public void deleteAllFlowableIdentifyData() throws Exception {
		this.activitiBaseService.deleteAllMemerShip();
		this.activitiBaseService.deleteAllRole();
		this.activitiBaseService.deleteAllUser();
	}
	

	/**
     * 同步所有角色数据到{@link Group}
	 * @throws Exception 
     */
    private void synRoleToFlowable() throws Exception {
        List<Role> allGroup = this.roleService.findList();
        for (Role group : allGroup) {
            String groupId = group.getRoleKey();
            Group identity_group = identityService.newGroup(groupId);
            identity_group.setName(group.getName());
            identity_group.setType(group.getType());
            try{
            	identityService.saveGroup(identity_group);
            }
            catch(RuntimeException e){
            	logger.warn(e.getMessage(),e);
            }
        }
    }
    
    /**
     * 复制用户以及关系数据
     * @throws Exception 
     */
    private void synUserWithRoleToFlowable() throws Exception {
        List<User> allUser = userService.findList(1);
        for (User user : allUser) {
            String userId = user.getLoginName();
            List<Role> roles = roleService.findUserRoles(user.getId());
            // 添加一个用户到Flowable
            activitiBaseService.saveFlowableUser(user);
 
            // 角色和用户的关系
            for(Role role: roles){
            	try{
            	  identityService.createMembership(userId, role.getRoleKey());
            	}
                catch(RuntimeException e){
                	logger.warn(e.getMessage(),e);
                }
            }
        }
    }
    
    /**
     * 更新用户时同事更新membership
     * @param user
     * @throws Exception
     */
    private void addMembership(User user) throws Exception{
    	for(Role role: user.getRoles()){
    		 this.activitiBaseService.addMembership(user.getLoginName(), role.getRoleKey());
        }    	
    }
	
}
